package com.ifuncat.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ifuncat.gulimall.common.utils.PageUtils;
import com.ifuncat.gulimall.common.utils.Query;
import com.ifuncat.gulimall.product.dao.CategoryDao;
import com.ifuncat.gulimall.product.entity.CategoryEntity;
import com.ifuncat.gulimall.product.service.CategoryBrandRelationService;
import com.ifuncat.gulimall.product.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listWithTree() {
        //1.查出所有分类
        List<CategoryEntity> entities = baseMapper.selectList(null);
        //2.组成树形结构
        List<CategoryEntity> topMenus = entities.stream().filter(entity -> entity.getParentCid() == 0) //一级菜单
                .peek(menu -> menu.setChildren(getChildren(menu, entities))) //设置子菜单
                .sorted(Comparator.comparingInt(CategoryEntity::getSort)) //根据排序字段升序排序
                .collect(Collectors.toList());


        return topMenus;
    }

    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> parentPath = findParentPath(catelogId, new ArrayList<>());
        Collections.reverse(parentPath);
        return parentPath.toArray(new Long[0]);
    }

    /**
     * 级联更新所有相关的数据, 在其他表存储category的字段需要同步更新
     */
    @Override
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        //同步更新其他关联表相关数据
        if (null != category.getCatId()) {
            categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
            //todo 更新其他关联表
        }
    }

    private List<Long> findParentPath(Long catelogId, List<Long> paths) {
        //先收集当前节点id
        paths.add(catelogId);
        //如果当前节点存在父节点,则收集父节点
        CategoryEntity entity = this.getById(catelogId);
        if (entity.getParentCid() != 0) {
            findParentPath(entity.getParentCid(), paths);
        }
        return paths;
    }

    /**
     * 递归查找菜单的子菜单
     */
    private List<CategoryEntity> getChildren(CategoryEntity root, List<CategoryEntity> fullList) {
        return fullList.stream().filter(entity -> Objects.equals(entity.getParentCid(), root.getCatId())) //找到当前菜单的所有子菜单
                .peek(entity -> entity.setChildren(getChildren(entity, fullList))) //递归设置子菜单
                .sorted((m1, m2) -> {
                    int s1 = null == m1.getSort() ? 0 : m1.getSort();
                    int s2 = null == m2.getSort() ? 0 : m2.getSort();
                    return s1 - s2;
                }) //根据排序字段升序排序
                .collect(Collectors.toList());
    }
}